Fix unable to re-split a transaction after its unreported sibling got deleted#91104
Conversation
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
|
@lakchote It works well for me. However, I noticed that when we delete the unreported split transaction, the |
Yes, this is expected since we didn't follow the traditional "Edit Splits" flow, which produces the revert if there's only one split transaction remaining upon saving.
We didn't enter the revert command; as a result, the logic behind it wasn't run. If we wanted to make it display this, it'd probably introduce edge cases for the |
Great. Thanks for the explanation. |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppandroid.hybrid.mp4Android: mWeb Chromeandroid.chrome.mp4iOS: HybridAppios.hybrid.mp4iOS: mWeb Safariios.safari.mp4MacOS: Chrome / Safarimac.safari.mp4 |
|
I found only one bug in the split per diem expense flow:
Video2026-05-21.09-30-31.mp4P.S. I have patched it myself to finalize this review soon. Here is my patch; you can refer to it to save your time: patchdiff --git a/src/hooks/useDeleteTransactions.ts b/src/hooks/useDeleteTransactions.ts
index f0e0e488f46..2baf4152dfe 100644
--- a/src/hooks/useDeleteTransactions.ts
+++ b/src/hooks/useDeleteTransactions.ts
@@ -15,6 +15,7 @@ import {getActiveGroupSearchHashes} from '@libs/SearchUIUtils';
import {
getChildTransactions,
getOriginalTransactionWithSplitInfo,
+ isPerDiemRequest,
isPerDiemRequest as isPerDiemRequestTransactionUtils,
shouldRedirectDeleteToSplitExpenseEdit,
} from '@libs/TransactionUtils';
@@ -92,13 +93,14 @@ function useDeleteTransactions({report, reportActions, policy}: UseDeleteTransac
}
const originalTransaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.comment?.originalTransactionID}`];
- if (!shouldRedirectDeleteToSplitExpenseEdit(transaction, originalTransaction)) {
+ const hasMultipleSplits = getChildTransactions(allTransactions, allReports, originalTransaction?.transactionID, true).length > 1;
+ if (!shouldRedirectDeleteToSplitExpenseEdit(transaction, originalTransaction) || (!hasMultipleSplits && isPerDiemRequest(originalTransaction))) {
return undefined;
}
return transaction;
},
- [allTransactions],
+ [allTransactions, allReports],
);
const shouldOpenSplitExpenseEditFlowOnDelete = useCallback(
|
|
Thanks for your diligence @dmkt9 I've applied your patch |
|
@madmax330 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
|
@madmax330 all yours |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚧 @madmax330 has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/madmax330 in version: 9.3.80-0 🚀
Bundle Size Analysis (Sentry): |
|
No help site changes are required for this PR. This is a bug fix to internal split-detection logic — it changes how the app determines whether a transaction is still part of an active split (counting actual live split children instead of checking report open status). The existing Split Expenses help article accurately describes all user-facing split workflows, and none of those documented behaviors or steps have changed. |
|
Deploy Blocker ##91481 was identified to be related to this PR |
|
🚀 Deployed to staging by https://github.com/madmax330 in version: 9.3.81-0 🚀
|
|
I reviewed the changes in this PR. This is an internal bug fix that corrects the logic for determining whether a transaction is still part of an active split after its sibling was deleted. The changes are limited to:
There are no changes to user-facing feature names, UI labels, workflows, or terminology. No help site documentation updates are required. |
Explanation of Change
If you split an expense, unreport one half and then delete that half, the leftover expense wouldn't let you split it again.
The old check for whether something is still a split wasn't reliable, so now it just looks at whether the split still has more than one expense in it (an unreported half still counts, a deleted one doesn't), which means the leftover behaves like a normal expense again.
Fixed Issues
$ #91105
PROPOSAL:
Tests
Expected Result: The reverted split transaction can be split normally.
Screen.Recording.2026-05-19.at.18.50.43.mov
Offline tests
NA
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
Same as in tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)myBool && <MyComponent />.src/languages/*files and using the translation methodWaiting for Copylabel for a copy review on the original GH to get the correct copy.STYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)/** comment above it */thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG))Avataris modified, I verified thatAvataris working as expected in all cases)ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari